package com.openlogic.logic.async;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.UploadedFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mybatisflex.core.query.QueryWrapper;
import com.openlogic.common.core.utils.ExcelUtil;
import com.openlogic.common.plugins.db.api.dto.BaseDataSourceColumnDto;
import com.openlogic.common.plugins.db.api.dto.BaseDataSourceTableDto;
import com.openlogic.common.plugins.db.api.utils.DataSourceUtils;
import com.openlogic.common.security.utils.SecurityUtil;
import com.openlogic.datasource.api.entity.DataColumnEntity;
import com.openlogic.datasource.api.entity.DataSourceEntity;
import com.openlogic.datasource.api.entity.DataTableEntity;
import com.openlogic.datasource.api.entity.table.Tables;
import com.openlogic.datasource.api.enums.SyncStatus;
import com.openlogic.logic.mapper.datasource.DataColumnMapper;
import com.openlogic.logic.mapper.datasource.DataSourceMapper;
import com.openlogic.logic.mapper.datasource.DataTableMapper;

import cn.hutool.core.collection.CollUtil;

/**
 * @ClassName: AsyncTask
 * @Description: 异步任务处理器
 * @author weiyongpeng
 * @date 2024年11月9日 下午2:41:56
 */
@Component(value = "asyncTask")
public class AsyncTask {

	private static final Logger log = LoggerFactory.getLogger(AsyncTask.class);

	@Inject
	private DataSourceMapper dataSourceMapper;

	@Inject
	private DataTableMapper dataTableMapper;

	@Inject
	private DataColumnMapper dataColumnMapper;

	/**
	* 描述：异步处理同步器
	* @Title: doTask
	* @param dataSourceEntity
	* @author weiyongpeng
	* @date  2024年11月22日 下午2:38:58
	 */
//	@Async("asyncRuleThreadExecutor")
	public void doTask(DataSourceEntity dataSourceEntity) {
		long start = System.currentTimeMillis();
		// 先删除元数据信息表
//		LambdaQueryWrapper<DataTableEntity> tableWrapper = new LambdaQueryWrapper<DataTableEntity>().eq(
//				!StringUtils.isEmpty(dataSourceEntity.getId()), DataTableEntity::getSourceId, dataSourceEntity.getId());
		QueryWrapper tableWrapper = QueryWrapper.create().where(Tables.dataTable.id.eq(dataSourceEntity.getId()));
		dataTableMapper.deleteByQuery(tableWrapper);
//		LambdaQueryWrapper<DataColumnEntity> columnWrapper = new LambdaQueryWrapper<DataColumnEntity>().eq(
//				!StringUtils.isEmpty(dataSourceEntity.getId()), DataColumnEntity::getSourceId,
//				dataSourceEntity.getId());
		QueryWrapper columnWrapper = QueryWrapper.create().where(Tables.dataColumn.sourceId.eq(dataSourceEntity.getId()));
		dataColumnMapper.deleteByQuery(columnWrapper);
		List<BaseDataSourceTableDto> tables = DataSourceUtils.getTables(dataSourceEntity);
		if (CollUtil.isNotEmpty(tables)) {
			List<DataTableEntity> metadataTableEntityList = tables.stream().map(table -> {
				DataTableEntity metadataTable = new DataTableEntity();
				metadataTable.setCreateBy(SecurityUtil.getLoginUser().getUsername());
				metadataTable.setUpdateBy(SecurityUtil.getLoginUser().getUsername());
				metadataTable.setSourceId(dataSourceEntity.getId());
				metadataTable.setTableName(table.getTableName());
				metadataTable.setTableComment(
						Optional.ofNullable(table.getTableComment()).isPresent() ? table.getTableComment()
								: table.getTableName());
				return metadataTable;
			}).collect(Collectors.toList());
			if (CollUtil.isNotEmpty(metadataTableEntityList)) {
				metadataTableEntityList.stream().forEach(table -> {
					dataTableMapper.insert(table);
					List<BaseDataSourceColumnDto> columns = DataSourceUtils.getColumns(dataSourceEntity,
							table.getTableName());
					if (CollUtil.isNotEmpty(columns)) {
						List<DataColumnEntity> metadataColumnEntityList = columns.stream().map(column -> {
							DataColumnEntity metadataColumn = new DataColumnEntity();
							metadataColumn.setCreateBy(SecurityUtil.getLoginUser().getUsername());
							metadataColumn.setUpdateBy(SecurityUtil.getLoginUser().getUsername());
							metadataColumn.setSourceId(dataSourceEntity.getId());
							metadataColumn.setTableId(table.getId());
							metadataColumn.setColumnName(column.getColName());
							metadataColumn.setColumnComment(
									Optional.ofNullable(column.getColComment()).isPresent() ? column.getColComment()
											: column.getColName());
							metadataColumn.setColumnKey(column.getColKey() ? "1" : "0");
							metadataColumn.setColumnNullable(column.getNullable() ? "1" : "0");
							metadataColumn.setColumnPosition(column.getColPosition().toString());
							metadataColumn.setDataType(column.getDataType());
							metadataColumn.setDataLength(column.getDataLength());
							metadataColumn.setDataPrecision(column.getDataPrecision());
							metadataColumn.setDataScale(column.getDataScale());
							metadataColumn.setDataDefault(column.getDataDefault());
							return metadataColumn;
						}).collect(Collectors.toList());
						if (CollUtil.isNotEmpty(metadataColumnEntityList)) {
							metadataColumnEntityList.stream().forEach(column -> dataColumnMapper.insert(column));
						}
					}
				});
			}
		}
		dataSourceEntity.setIsSync(SyncStatus.IsSync.getKey());
		dataSourceMapper.update(dataSourceEntity);
		log.info("异步任务执行完成！耗时{}秒", (System.currentTimeMillis() - start / 1000));
	}
	
//	@Async("asyncRuleThreadExecutor")
	public void doTaskReadExcel(UploadedFile file, String dbPath, DataSourceEntity dataSourceEntity) {
		long start = System.currentTimeMillis();
		// 先删除元数据信息表
//		LambdaQueryWrapper<DataTableEntity> tableWrapper = new LambdaQueryWrapper<DataTableEntity>().eq(
//		!StringUtils.isEmpty(dataSourceEntity.getId()), DataTableEntity::getSourceId, dataSourceEntity.getId());
		QueryWrapper tableWrapper = QueryWrapper.create().where(Tables.dataTable.id.eq(dataSourceEntity.getId()));
		dataTableMapper.deleteByQuery(tableWrapper);
//		LambdaQueryWrapper<DataColumnEntity> columnWrapper = new LambdaQueryWrapper<DataColumnEntity>().eq(
//		!StringUtils.isEmpty(dataSourceEntity.getId()), DataColumnEntity::getSourceId,
//		dataSourceEntity.getId());
		QueryWrapper columnWrapper = QueryWrapper.create()
				.where(Tables.dataColumn.sourceId.eq(dataSourceEntity.getId()));
		dataColumnMapper.deleteByQuery(columnWrapper);
		// 解析excel的sheet作为表，解析sheet的column作为列
		Workbook workbook = ExcelUtil.getWorkbook(file,dbPath);
		String sheetName = null;
		if (Objects.nonNull(workbook)) {
			// 列项
			sheetName = ExcelUtil.getSheetName(workbook);
		}

		if (StringUtils.isNotBlank(sheetName)) {
			List<DataTableEntity> metadataTableEntityList = Arrays.asList(sheetName).stream().map(table -> {
				DataTableEntity metadataTable = new DataTableEntity();
				metadataTable.setCreateBy(SecurityUtil.getLoginUser().getUsername());
				metadataTable.setUpdateBy(SecurityUtil.getLoginUser().getUsername());
				metadataTable.setSourceId(dataSourceEntity.getId());
				metadataTable.setTableName(table);
				metadataTable.setTableComment(table);
				return metadataTable;
			}).collect(Collectors.toList());
			if (CollUtil.isNotEmpty(metadataTableEntityList)) {
				metadataTableEntityList.stream().forEach(table -> {
					dataTableMapper.insert(table);
					List<Cell> sheetTitles = ExcelUtil.getSheetTitles(workbook);
					if (CollUtil.isNotEmpty(sheetTitles)) {
						List<DataColumnEntity> metadataColumnEntityList = sheetTitles.stream().map(column -> {
							DataColumnEntity metadataColumn = new DataColumnEntity();
							metadataColumn.setCreateBy(SecurityUtil.getLoginUser().getUsername());
							metadataColumn.setUpdateBy(SecurityUtil.getLoginUser().getUsername());
							metadataColumn.setSourceId(dataSourceEntity.getId());
							metadataColumn.setTableId(table.getId());
							metadataColumn.setColumnName(column.getStringCellValue());
							metadataColumn.setColumnComment(column.getStringCellValue());
							metadataColumn.setDataType(column.getCellType().name());
							return metadataColumn;
						}).collect(Collectors.toList());
						if (CollUtil.isNotEmpty(metadataColumnEntityList)) {
							metadataColumnEntityList.stream().forEach(column -> dataColumnMapper.insert(column));
						}
					}
				});
			}
		}
		// 同步完毕，需要发送消息，提醒用户刷新缓存
		dataSourceEntity.setIsSync(SyncStatus.IsSync.getKey());
		dataSourceMapper.update(dataSourceEntity);
		log.info("异步任务执行完成！耗时{}秒", (System.currentTimeMillis() - start / 1000));
	}

}